package kr.co.bettersoft.waitnumbercustomer.activity;

import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import kr.co.bettersoft.waitnumbercustomer.common.CommonConstant;
import kr.co.bettersoft.waitnumbercustomer.common.WaitNumberCustomerRest;
import kr.co.bettersoft.waitnumbercustomer.domain.MemberUser;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.ProgressBar;
import android.widget.Toast;

/**
 * PrefActivity
 * 메인 탭 4 - 설정 액티비티
 *  사용자 설정 : 인증 정보 / 이메일 입력 / 알림 수신 설정
 *  기본정보 : 자주묻는질문 / 공지사항 / 이용약관 / 개인정보취급방침 / 왓 이즈 디스 앱
 * 
 * 인증정보는 인증받은 전화번호 정보를 알 수 있다.
 * 이메일 입력은 사용자 이메일을 등록/수정 할수 있다.
 * 알림 수신설정을 통해 서버로부터 푸시 알림을 수신할지 여부를 설정할 수 있다.
 * 
 * 자주묻는질문/공지사항/이용약관/개인정보취급방침은 웹 페이지를 웹뷰를 통해 보여준다.
 * 왓 이즈 디스 앱 은 어플 이미지 및 어플에 대한 간략한 설명문구를 보여주는 화면이며, 화면 터치시 설정화면으로 돌아온다.
 */
public class PrefActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener{
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 변수	

	static String TAG = "PrefActivity";

	public final int GET_USER_INFO = 501; //  서버로부터 개인 정보를 받아와서 도메인에 저장한다
	public final int UPDATE_TO_SERVER = 502; //  서버로 변경된 설정 등을 업데이트 한다
	public final int UPDATE_GCM_TO_SERVER = 503; //  서버에 알림 수신 설정 값을 업뎃한다

	DummyActivity dummyActivity = (DummyActivity)DummyActivity.dummyActivity;

	// Locale
	Locale systemLocale = null ;
	String strCountry = "" ;				// 국가 코드
	String strLanguage = "" ;				// 언어 코드

	// pref
	SharedPreferences sharedPrefCustom;	// 공용 프립스	 	
	SharedPreferences thePrefs;				// 어플 내 자체 프리퍼런스.  Resume 때 이곳에 연결하여 사용 
	SharedPreferences defaultPref;			// default --   자체 프리퍼런스. 
	int sharePrefsFlag = 1;					 
	public Boolean resumeCalled = false;  // 처음 열렸는지, 다른 화면 갔다온건지. -- 처음열렸을때만 프리퍼런스 지정하기 위함.

	// 서버 통신 관련
//	WaitNumberCustomerRest waitNumberCustomerRest;
//	String callResult = "";
//	String tempstr = "";
//	JSONObject jsonObject;

	static int updateLv=0;							// 서버에 업뎃 칠지 여부 검사용도. 0이면 안하고, 1이면 한다, 2면 두번한다(업뎃중 값이 바뀐 경우 )
	// 중복 실행 방지용
	int isUpdating = 0;


	// GCM 받을지 여부 저장. 메서드용.
	String strYorN = "";
	Boolean yn = false;

	// 전번(업뎃용)
	String phoneNum = "";
	// qr
	String qrCode = "";
	// 케릭 설정 정보 저장해 놓을 도메인. 항상 최신 정보를 유지해야 한다.
	MemberUser memberInfo;


	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 핸들러 등록					
	Handler handler = new Handler(){
		@Override
		public void handleMessage(Message msg){
			Bundle b = msg.getData();
			
			switch (msg.what)
			{
				case GET_USER_INFO   : runOnUiThread(new RunnableGetUserInfo());
					break;
				case UPDATE_TO_SERVER   : runOnUiThread(new RunnableUpdateToServer());
					break;
				case UPDATE_GCM_TO_SERVER   : runOnUiThread(new RunnableUpdateGCMToServer());
					break;
				default : 
					break;
			}
		}
	};
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
//		requestWindowFeature( Window.FEATURE_NO_TITLE );		// no title  에러남
		
		addPreferencesFromResource(R.xml.settings);

//		WaitNumberCustomerRest waitNumberCustomerRest = new WaitNumberCustomerRest();

		/*
		 *  서버로부터 개인 정보를 가져와서 도메인 같은 곳에 담아둔다. 나중에 업데이트 할때 사용 . 업데이트하고 나면 그 도메인 그대로 유지 ..
		 *  없는거는 null pointer 나므로 ""로 바꿔주는 처리가 필요하다.
		 */
		memberInfo = new MemberUser();
		handler.sendEmptyMessage(GET_USER_INFO);
		isUpdating=1;		// onresume 의 것과 충돌하지 않고 하나만 실행되도록..

		if(!resumeCalled){			// 한번만
			getPreferenceScreen().getSharedPreferences() 
			.registerOnSharedPreferenceChangeListener(this);		// 리스너 등록 

			// prefs 	// 공용으로 쓸것도 필요하다. 
			sharedPrefCustom = getSharedPreferences(CommonConstant.prefName,
					Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
			sharedPrefCustom.registerOnSharedPreferenceChangeListener(this);			// 여기에도 등록해놔야 리시버가 제대로 반응한다.
			// default 도  등록해야 함
			defaultPref = PreferenceManager.getDefaultSharedPreferences(this);
			defaultPref.registerOnSharedPreferenceChangeListener(this);			 
			qrCode = sharedPrefCustom.getString("qrCode","");		// 저장된 QR코드 꺼냄

			// 프리퍼런스 동기화 (공유용 - 디폴트 간 동기화)
			SharedPreferences.Editor init2 = sharedPrefCustom.edit();		// 강제 호출용도 
			int someNum = sharedPrefCustom.getInt("pref_app_hi", sharePrefsFlag);	// 이전 값과 같을수 있으므로..
			someNum = someNum * -1;													// 매번 다른 값이 들어가야 제대로 호출이 된다. 같은 값들어가면 변화 없다고 호출 안됨.			
			init2.putInt("pref_app_hi", someNum); 		// 프리퍼런스 값 넣어 업데이트 시키면 강제로 리스너 호출.
			init2.commit();			

			resumeCalled = true;
		}
	}


	//////////////////////////// /////////////////////////////////////	

	public void saveGCMEnableToPref(){
		SharedPreferences.Editor saveGCMCustom = sharedPrefCustom.edit();		// 공용에 저장해 준다.
		yn = ((CheckBoxPreference)findPreference("preference_alarm_chk")).isChecked();
		saveGCMCustom.putBoolean("gcmReceive", yn);
		saveGCMCustom.commit();
		Log.d(TAG,"S to save GCM setting to pref.");
	}


	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


	/**
	 * 러너블. 서버로부터 개인 정보를 받아와서 도메인에 저장한다
	 */
	class RunnableGetUserInfo implements Runnable {
		public void run(){
			new backgroundThreadGetUserInfo().execute();
		}
	}
	/**
	 * backgroundThreadGetUserInfo
	 * 비동기 스레드.  서버로부터 개인 정보를 받아와서 도메인에 저장한다
	 * @author blue
	 *
	 */
	public class backgroundThreadGetUserInfo extends AsyncTask<Void, Void, Void>{
		@Override protected void onPostExecute(Void result) {  
		} 
		@Override protected void onPreExecute() {  
		} 
		@Override protected Void doInBackground(Void... params) {  
			Log.d(TAG,"backgroundThreadGetUserInfo");

			// 파라미터 세팅
			MemberUser memberUserParam = new MemberUser();
			memberUserParam.setQrCode(qrCode);
			// 서버 메소드 호출
			WaitNumberCustomerRest waitNumberCustomerRest = new WaitNumberCustomerRest();
			String callResult = waitNumberCustomerRest.RestGetMemberInfo(memberUserParam);
			// 결과 처리 
			if(!(callResult.equals("F"))){
				String tempDataStr = "";
				if(callResult.length()!=0){
					try {
						JSONObject jsonObject = new JSONObject(callResult);
						try{	// 멜
							tempDataStr = jsonObject.getString("email");
							if(tempDataStr==null || tempDataStr.length()<1 || tempDataStr.equals("null")){
								tempDataStr = "";
							}
						}catch(Exception e){ tempDataStr = ""; }
						memberInfo.setEmail(tempDataStr);

						SharedPreferences.Editor savePrefUserEmail = sharedPrefCustom.edit();		// 공용에 저장해 준다.
						savePrefUserEmail.putString("pref_user_email", tempDataStr);
						savePrefUserEmail.commit();

					} catch (JSONException e) {
						e.printStackTrace();
					} 
				}
			}
			return null; 
		}
	}


	/**
	 * 러너블. 서버로 변경된 설정 등을 업데이트 한다
	 */
	class RunnableUpdateToServer implements Runnable {
		public void run(){
			new backgroundThreadUpdateToServer().execute();
		}
	}
	/**
	 * backgroundThreadUpdateToServer
	 * 비동기 스레드.  서버로 변경된 설정 등을 업데이트 한다
	 * @author blue
	 *
	 */
	public class backgroundThreadUpdateToServer extends AsyncTask<Void, Void, Void>{
		@Override protected void onPostExecute(Void result) {  
		} 
		@Override protected void onPreExecute() {  
		} 
		@Override protected Void doInBackground(Void... params) {  
			Log.d(TAG,"backgroundThreadUpdateToServer");

			// 파라미터 세팅
			MemberUser memberUserParam = new MemberUser();
			memberUserParam.setQrCode(qrCode);
			memberUserParam.setEmail(memberInfo.getEmail());
			// 서버 메소드 호출
			WaitNumberCustomerRest waitNumberCustomerRest = new WaitNumberCustomerRest();
			String callResult = waitNumberCustomerRest.RestUpdateToServer(memberUserParam);
			// 결과 처리 
			if(!(callResult.equals("F"))){
				try {
					JSONObject jsonObject = new JSONObject(callResult);
					String strResult = jsonObject.getString("result").toString(); 
//					Log. d(TAG,"strResult:"+strResult);
					if((strResult.equals("SUCCESS"))){
						Log.d(TAG,"S to update to server");
						updateLv = updateLv-1;
						if(updateLv>0){		// 2였던 경우. (업뎃중 또 변경된 경우 한번더)
							Log.d(TAG,"Need Update one more time");
							handler.sendEmptyMessage(GET_USER_INFO);
						}
					}
				} catch (JSONException e) {
					e.printStackTrace();
				} 
			}else{
				Log.w(TAG,"fail to update");
			}
			return null; 
		}
	}

	/**
	 * 러너블.서버에 알림 수신 설정 값을 업뎃한다
	 */
	class RunnableUpdateGCMToServer implements Runnable {
		public void run(){
			new backgroundThreadUpdateGCMToServer().execute();
		}
	}
	/**
	 * backgroundThreadUpdateGCMToServer
	 * 비동기 스레드.  서버에 알림 수신 설정 값을 업뎃한다
	 * @author blue
	 *
	 */
	public class backgroundThreadUpdateGCMToServer extends AsyncTask<Void, Void, Void>{
		@Override protected void onPostExecute(Void result) {  
		} 
		@Override protected void onPreExecute() {  
		} 
		@Override protected Void doInBackground(Void... params) {  
			Log.d(TAG,"backgroundThreadUpdateGCMToServer");

			// 파라미터 세팅
			MemberUser memberUserParam = new MemberUser();
			memberUserParam.setQrCode(qrCode);
			if(yn){
				strYorN="Y";
			}else{
				strYorN="N";
			}
			memberUserParam.setReceiveNotificationYn(strYorN);
			// 서버 메소드 호출
			WaitNumberCustomerRest waitNumberCustomerRest = new WaitNumberCustomerRest();
			String callResult = waitNumberCustomerRest.RestUpdateGCMToServer(memberUserParam);
			// 결과 처리 
			updateLv = updateLv-1;
			if(updateLv>0){		// 2였던 경우. (업뎃중 또 변경된 경우 한번더)
				Log.d(TAG,"Need Update one more time");
				handler.sendEmptyMessage(UPDATE_GCM_TO_SERVER);
			}

			if(!(callResult.equals("F"))){
				try {
					JSONObject jsonObject = new JSONObject(callResult);
					if((jsonObject.getString("result")).equals("SUCCESS")){
						Log.d(TAG, "S to receive GCM option update");
						saveGCMEnableToPref();		// 자체 설정에도 저장.
					}
				} catch (Exception e) {		
					e.printStackTrace();
					Log.w(TAG,callResult.length()+"");		// 0 이면 서버에 정보 없음.
				} 
			}
			return null; 
		}
	}

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 자체 기능	

	// Preference에서 클릭 발생시 호출되는 call back
	// Parameters:
	//  - PreferenceScreen : 이벤트가 발생한 Preference의 root
	//  - Preference : 이벤트를 발생시킨 Preference 항목
	/**
	 * onPreferenceTreeClick
	 *  프리퍼런스 클릭시 호출되는 콜백메서드이다. 설정 값 변화 또는 설정 메뉴 호출 등이 있다.
	 *
	 * @param preferenceScreen
	 * @param preference
	 * @return
	 */
	@Override
	public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
			Preference preference) {

		// 알림 수신 설정 여부.
		if(preference.equals((CheckBoxPreference)findPreference("preference_alarm_chk"))){
			yn = ((CheckBoxPreference)findPreference("preference_alarm_chk")).isChecked();
			// 서버에 업뎃 
			if(updateLv<2){		// 0또는 1일경우. 1 증가. (최대 2까지)
				updateLv = updateLv+1;
				if(updateLv==1){
					handler.sendEmptyMessage(UPDATE_GCM_TO_SERVER);
				}
			}
		}

		// 자주 묻는 질문 등의 경우 인텐트로 웹뷰 실시
		if(preference.equals(findPreference("pref_app_qna"))){
			Intent webIntent = new Intent(PrefActivity.this, myWebView.class);
			webIntent.putExtra("loadingURL", CommonConstant.qnaURL);
			webIntent.putExtra("webViewTitle", getString(R.string.pref_app_qna));
			startActivity(webIntent);
		}

//		// 공지사항.  pref_app_notify
//		if(preference.equals(findPreference("pref_app_notify"))){
//			Intent webIntent = new Intent(PrefActivity.this, myWebView.class);
//			webIntent.putExtra("loadingURL", CommonConstant.noticeURL);
//			webIntent.putExtra("webViewTitle", getString(R.string.pref_app_notify));
//			startActivity(webIntent);
//		}

		// 이용 약관..  pref_app_terms
		if(preference.equals(findPreference("pref_app_terms"))){
			Intent webIntent = new Intent(PrefActivity.this, myWebView.class);
			webIntent.putExtra("loadingURL", CommonConstant.termsPolicyURL);
			webIntent.putExtra("webViewTitle", getString(R.string.pref_app_terms));
			startActivity(webIntent);
		}
		// 개인정보 보호정책..  pref_app_privacy
		if(preference.equals(findPreference("pref_app_privacy"))){
			Intent webIntent = new Intent(PrefActivity.this, myWebView.class);
			webIntent.putExtra("loadingURL", CommonConstant.privacyPolicyURL);
			webIntent.putExtra("webViewTitle", getString(R.string.pref_app_privacy));
			startActivity(webIntent);
		}
		
		// 이벤트 알림  pref_push_list
		if(preference.equals(findPreference("pref_push_list"))){
			Intent PushListIntent = new Intent(PrefActivity.this, EventListActivity.class);
			startActivity(PushListIntent);

		}
		// 이 앱은 ? pref_app_what
		if(preference.equals(findPreference("pref_app_what"))){
			Intent aboutIntent = new Intent(PrefActivity.this, PrefAboutThisAppActivity.class);
			startActivity(aboutIntent);
		}

		return super.onPreferenceTreeClick(preferenceScreen, preference);
	}	



	// 주 용도는 resume 때 자체 프리퍼런스 전달하여 컨트롤 할 수 있게 하는 것. 
	/**
	 * onSharedPreferenceChanged
	 *  default 프리퍼런스 변화가 있을때의 콜백 메서드 이다.
	 *   default 프리퍼런스와 공유 preference 간 동기화를 위한 작업을 한다
	 *
	 * @param sharedPreferences
	 * @param key
	 * @return
	 */
	@Override
	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
			String key) {
		if(key.equals("pref_app_hi")){		// resume 에서 넣은 것과 이름 일치해야 동작한다.
			thePrefs = sharedPreferences;
		}
	}


	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 유틸	

	// 준비중입니다.. -> 이벤트 목록 미구현 상태일때 알림 용도 --> 현재는사용하지 않음
	public void AlertShow_Message(){		//R.string.network_error
		AlertDialog.Builder alert_internet_status = new AlertDialog.Builder(this);
		alert_internet_status.setTitle(R.string.title_app);
		alert_internet_status.setMessage(R.string.not_yet);
		String tmpstr = getString(R.string.closebtn);
		alert_internet_status.setPositiveButton(tmpstr, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}
		});
		alert_internet_status.show();
	}

	/**
	 * isValidEmail
	 * 이메일주소 유효검사
	 * 
	 * @author   Sehwan Noh <sehnoh@gmail.com>
	 * @version  1.0 - 2006. 08. 22
	 * @since    JDK 1.4
	 * @param email
	 */
	public static boolean isValidEmail(String email) {
		Pattern p = Pattern.compile("^(?:\\w+\\.?)*\\w+@(?:\\w+\\.)+\\w+$");
		Matcher m = p.matcher(email);
		return m.matches();
	}

	@Override
	public void onResume(){		
		super.onResume();
		getPreferenceScreen().getSharedPreferences() 
		.registerOnSharedPreferenceChangeListener(this); 		// 리스너 등록
	}
	/**
	 * onPause
	 * 액티비티 중지시 스레드를 초기화한다.
	 */
	@Override 
	protected void onPause() { 
		super.onPause(); 
		getPreferenceScreen().getSharedPreferences() 
		.unregisterOnSharedPreferenceChangeListener(this); 		// 리스너 해제
	} 

	@Override			// 이 액티비티가 종료될때 실행. 
	protected void onDestroy() {
		resumeCalled = false;		// 또 불러 주십시오.
		super.onDestroy();
	}

}
